package com.rodirod.vrmonitor;

import java.util.List;
import java.util.Map;

import com.rodirod.vrmonitor.R;

import android.app.ListActivity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.AdapterContextMenuInfo;

public class HomeActivity extends ListActivity implements Constants {
	
	// key for startActivityForResult;
	private final int I_ADD_RACE = 0;
	private String raceKeyToAdd_ = null;
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// Check that data connection is available : TODO
		boolean networkState = this.getIntent().getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY , true);

		if (networkState) {
			
			// Check that user name is defined
			SharedPreferences prefs = getSharedPreferences(KEY_PREFS,Context.MODE_PRIVATE);
			String userCode = prefs.getString(P_USER_CODE,null);
			
			if (null==userCode) {
				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setMessage("User code is not defined. Please defined it first.");
				builder.setCancelable(false);
				builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						dialog.cancel();
					}
				});
				builder.create();
				builder.show();
			} else {
				initDataFromPreferences();
			}
			
			// Construct the adapter
			SimpleAdapter mList = new SimpleAdapter(this, 
					updateAdapterViewData(), 
					R.layout.regate_list_item, 
					new String[] {M_REGATE_ICON, M_REGATE_NAME},
					new int[] {R.id.regate_row_icon, R.id.regate_row_name});
			setListAdapter(mList);
			
			// allow fast access with keyboard
			ListView lv = getListView();
			lv.setTextFilterEnabled(true);

			// add context menu on items
			registerForContextMenu(lv);
			
			// start SupervisionService
			Intent intent = new Intent(this,SupervisionService.class);
			startService(intent);

		} else {
			// show error dialog
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("Aucune connexion au réseau.... \nvous devez être connecté à internet pour utiliser l'application");
			builder.setCancelable(false);
			builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {
					dialog.cancel();
				}
			});
			builder.create();
			builder.show();
		}

		// TODO : 
		//   - ne pas lire le site avant d'avoir cliquer sur la liste!
		//	 - stockage des paramètres supervisés (persistence)
		//   - stockage de la valeur de référence + derniere valeur
		//   - notification si chgt / référence : see NotificationManager + sample NotificationService.java
		//   - saisie des parametres
		//          - forme de notif (barre+son/vibreur)
		//          - demarrage auto
		//   - demarrage auto si connexion data dispo
		//   - stockage de la route effectuée + interface vers Google MAP
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		RaceManager rm = RaceManager.getInstance();
		rm.clearAndDestroy();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		
		super.onCreateContextMenu(menu, v, menuInfo);
				
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.layout.race_context_menu, menu);
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo)item.getMenuInfo();
		View v = adapterMenuInfo.targetView;
		Map<String,Object> data = (Map<String,Object>)((ListView)v.getParent()).getItemAtPosition(adapterMenuInfo.position);
		String raceName = (String)data.get(M_REGATE_NAME);
		String raceKey = (String)data.get(M_REGATE_KEY);
		RaceManager rm = RaceManager.getInstance();
		
		switch (item.getItemId()) {
		case R.id.race_delete:
			rm.removeRace(raceName);
			// unlock the race name in main prefs
        	SharedPreferences prefs = getSharedPreferences(KEY_PREFS,Context.MODE_PRIVATE);
    		Editor ed = prefs.edit();
    		ed.putBoolean(raceKey,Boolean.FALSE );
    		ed.commit();
    		
    		this.updateAdapterViewData();
    		
    		SimpleAdapter mList = (SimpleAdapter)this.getListAdapter();
    		mList.notifyDataSetChanged();
			break;
		case R.id.race_settings:
			// TODO
			break;
		default:
			return super.onContextItemSelected(item);
		}
		
		return true;
	}
	
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		RaceManager dataManager = RaceManager.getInstance();
		List<Map<String, Object>> regateList = dataManager.getAdapterViewData();
		
        String regateName = (String) regateList.get((int) id).get(M_REGATE_NAME);
        Class<?> activityClass = (Class<?>) regateList.get((int) id).get(M_REGATE_ACTIVITY);
        
        if (activityClass != null)
        {
        	Intent intent = new Intent(this, activityClass);
            intent.putExtra(M_EXTRA_REGATE_NAME, regateName);
            intent.putExtra(M_EXTRA_NOTIFICATION_ID, -1);
            startActivity(intent);
        }
	}

	/**
	 * Load the races from shared preferences
	 * @return true if ok, false otherwise
	 */
	private boolean initDataFromPreferences() {
		SharedPreferences prefs = getSharedPreferences(KEY_PREFS,Context.MODE_PRIVATE);
		String userCode = prefs.getString(P_USER_CODE,null);
		if (null==userCode) return false;
		
		boolean resultOk = true;
		
		for (int i=0;i<MAX_RACE;i++) {
			String race_key = getPreferenceKeyForRace(i);
			Boolean result = prefs.getBoolean(race_key, Boolean.FALSE);
			if (result.equals(Boolean.TRUE)) {
				resultOk = resultOk && initRaceFromPrefs(race_key);
			}
		}
		
		return resultOk;
	}

	/**
	 * constructs the preference name for the race number i
	 * @param i
	 * @return
	 */
	private String getPreferenceKeyForRace(int i) {
		return "race_name_"+i;
	}


	/**
	 * update the data for the listAdapter
	 * @return data for the listAdapter
	 */
	private List<? extends Map<String, Object>> updateAdapterViewData() {
		RaceManager dataManager = RaceManager.getInstance();
		List<Map<String, Object>> result = dataManager.getAdapterViewData();

		Map<String,Object> map;

		for (int i=0 ; i<result.size(); i++) {
			map = result.get(i);
			map.put(M_REGATE_ICON,R.drawable.regate_icon);
			map.put(M_REGATE_ACTIVITY,RaceDetailedViewActivity.class);
		}
		return result;
	}


	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		
		super.onCreateOptionsMenu(menu);
		
        menu.add(0, MENU_OPTION_ADD_RACE, 0, R.string.vr_option_menu_add_regatte).setIcon(android.R.drawable.ic_menu_add);
        menu.add(0, MENU_OPTION_CONFIG, 0, R.string.vr_option_menu_config).setIcon(android.R.drawable.ic_menu_preferences);
        menu.add(0, MENU_OPTION_ABOUT, 1, R.string.vr_option_menu_about).setIcon(android.R.drawable.ic_menu_info_details);
        menu.add(0, MENU_OPTION_QUIT, 2, R.string.vr_option_menu_quit).setIcon(android.R.drawable.ic_menu_close_clear_cancel);

        return true;
	}


	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent i;

    	switch (item.getItemId())
    	{
			case MENU_OPTION_ADD_RACE:
				// define a new race in main properties
				raceKeyToAdd_ = defineRaceKey();
				i = new Intent(this, RaceSettingsActivity.class);
				i.putExtra(M_EXTRA_REGATE_NAME, raceKeyToAdd_);
		    	startActivityForResult(i,I_ADD_RACE);
		    	return true;
    		case MENU_OPTION_CONFIG:
    			i = new Intent(this, ApplicationSettingsActivity.class);
		    	startActivity(i);
		    	return true;
    		case MENU_OPTION_ABOUT:
    			displayAbout();
		    	return true;
    		case MENU_OPTION_QUIT:
    			finish();
		    	return true;
    		default:
        }
        return super.onOptionsItemSelected(item);	
    }
	
	@Override
	protected void onActivityResult(int requestCode, 
			int resultCode,
            Intent data) {
		
		super.onActivityResult(requestCode, resultCode, data);
		
        if (requestCode == I_ADD_RACE) {
        	boolean resultOk = initRaceFromPrefs(raceKeyToAdd_);
        	
        	if (!resultOk) {
        		AlertDialog.Builder builder = new AlertDialog.Builder(this);
        		builder.setMessage("Cannot get information from base URL or user is unknown.");
        		builder.setCancelable(false);
        		builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        			public void onClick(DialogInterface dialog, int id) {
        				dialog.cancel();
        			}
        		});
        		builder.create();
        		builder.show();
        	} else {
        		// lock the race name in main prefs
            	SharedPreferences prefs = getSharedPreferences(KEY_PREFS,Context.MODE_PRIVATE);
        		Editor ed = prefs.edit();
        		ed.putBoolean(raceKeyToAdd_,Boolean.TRUE );
        		ed.commit();
        		
        		updateAdapterViewData();
        		
        		SimpleAdapter mList = (SimpleAdapter)this.getListAdapter();
        		mList.notifyDataSetChanged();
        	}
        }
    }

	/**
	 * load a race from its parameter file
	 * @param race_name
	 * @return
	 */
	private boolean initRaceFromPrefs(String race_key) {
    	// get the race properties
    	SharedPreferences prefs = getSharedPreferences(KEY_PREFS,Context.MODE_PRIVATE);
    	String userCode = prefs.getString(P_USER_CODE,null);
    	
    	SharedPreferences sp = getSharedPreferences(race_key,Context.MODE_PRIVATE);
    	String baseUrl = sp.getString("base_url", null);

    	boolean resultOk = false;
    	
    	if (null!=baseUrl && null!=userCode) {
    		// Open the URL, retrieve data and store it to the datamanager
    		RaceManager dataManager = RaceManager.getInstance();
    		String regateName=sp.getString("name", "unknown");

    		String urlPath = baseUrl + "/profil.php?id_user="+userCode+"&langue=FR";
    		resultOk = dataManager.addRace(regateName,race_key,urlPath);
    	}
    	
    	return resultOk;
	}


	/*
	 * return the first preference key which is free for a new race storage
	 */
	private String defineRaceKey() {
		/**
		 *  get main preferences : we have MAX_RACES parameters which contain true or false :
		 *  true if the race is defined, false otherwise
		 */
		SharedPreferences sp = getSharedPreferences(KEY_PREFS,Context.MODE_PRIVATE);
		// find the first property available
		String race_name = null;
		Boolean result = Boolean.TRUE;
		for (int i=0;i<MAX_RACE && result;i++) {
			race_name = getPreferenceKeyForRace(i);
			result = sp.getBoolean(race_name, Boolean.FALSE);
		}
		if (result==Boolean.TRUE) {
			// all the races are defined, return null
			return null;
		}
		// return the name of the property
		return race_name;
	}


	/**
	 * display about text
	 */
	private void displayAbout()
    {	
    	AlertDialog d = new AlertDialog.Builder(this).create();
    	ScrollView s = new ScrollView(this);
    	TextView t = new TextView(this);
    	t.setLinksClickable(true);
    	t.setAutoLinkMask(Linkify.ALL);
    	
    	PackageManager pm = getApplicationContext().getPackageManager();
    	String version = "not_found";
		try {
			version = pm.getPackageInfo(this.getPackageName(),PackageManager.GET_ACTIVITIES).versionName;
		} catch (NameNotFoundException e) {	}
    	
    	t.setText("Virtual Regatta Notifier est une application indépendante de Virtual Regatta.\n\n"+
			"Site web :\nhttp://XXXXXXXXXXXXXX\n\n"+
			"Contact :\nXXXXXXXXXX\n\n"+
			"Version : "+version+"\n\n"+
			"Auteurs :\n"+
			"- Rodolphe Rousselet\n"+
			"\n"+
			"Cette application utilise :\n"+
			"- Jericho HTML Parser : http://jericho.htmlparser.net/docs/index.html\n"+
			"- Icônes Tango : http://tango.freedesktop.org/\n" +
			"\n"
			);
    	s.setPadding(10,10,10,10);
    	t.setMovementMethod(LinkMovementMethod.getInstance());
    	t.setTextColor(0xffffffff);
    	t.setLinkTextColor(0xffffffff);
    	t.setTextSize(16);
    	s.addView(t);
    	d.setView(s);
		d.setTitle(getString(R.string.app_name));
		d.setButton(DialogInterface.BUTTON_POSITIVE, "Ok", new DialogInterface.OnClickListener()
			{
				public void onClick(DialogInterface dialog, int which)
				{
					dialog.dismiss();
				}
			});
		d.show();
    }
}